import {
	Connector
} from './connector';
import {
	WeappSocketChannel,
	WeappSocketPriviateChannel,
	WeappSoketPresenceChannel
} from '../channel';

/**
 * This class creates a connnector to a Socket.io server.
 */
export class WeappSocketConnector extends Connector {
	/**
	 * The Socket.io connection instance.
	 */
	socket;

	/**
	 * All of the subscribed channel names.
	 */
	channels = {};
	constructor(options) {
		super(options)
		this.connect()
		
		
	}
	/**
	 * Create a fresh Socket.io connection.
	 */
	connect() {
		let io = this.getSocketIO();

		this.socket = io(this.options.host, this.options);
		return this.socket;
	}

	/**
	 * Get socket.io module from global scope or options.
	 */
	getSocketIO() {
		if (typeof io !== 'undefined') {
			return io;
		}

		if (typeof this.options.client !== 'undefined') {
			return this.options.client;
		}

		throw new Error('Socket.io client not found. Should be globally available or passed via options.client');
	}

	/**
	 * Listen for an event on a channel instance.
	 */
	listen(name, event, callback) {
		return this.channel(name).listen(event, callback);
	}

	/**
	 * Get a channel instance by name.
	 */
	channel(name) {
		if (!this.channels[name]) {
			this.channels[name] = new WeappSocketChannel(
				this.socket,
				name,
				this.options
			);
		}

		return this.channels[name];
	}

	/**
	 * Get a private channel instance by name.
	 */
	privateChannel(name) {
		if (!this.channels['private-' + name]) {
			this.channels['private-' + name] = new WeappSocketPriviateChannel(
				this.socket,
				'private-' + name,
				this.options
			);
		}

		return this.channels['private-' + name];
	}

	/**
	 * Get a presence channel instance by name.
	 */
	presenceChannel(name) {
		if (!this.channels['presence-' + name]) {
			this.channels['presence-' + name] = new WeappSoketPresenceChannel(
				this.socket,
				'presence-' + name,
				this.options
			);
		}

		return this.channels['presence-' + name];
	}

	/**
	 * Leave the given channel, as well as its private and presence variants.
	 */
	leave(name) {
		let channels = [name, 'private-' + name, 'presence-' + name];

		channels.forEach(name => {
			this.leaveChannel(name);
		});
	}

	/**
	 * Leave the given channel.
	 */
	leaveChannel(name) {
		if (this.channels[name]) {
			this.channels[name].unsubscribe();

			delete this.channels[name];
		}
	}

	/**
	 * Get the socket ID for the connection.
	 */
	socketId() {
		return this.socket.id;
	}

	/**
	 * Disconnect Socketio connection.
	 */
	disconnect() {
		this.socket.disconnect();
	}
}
